package com.apikey.auth.controller;

import com.apikey.auth.entity.AccessLog;
import com.apikey.auth.service.AccessLogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 访问日志控制器
 * 提供访问日志查询和统计接口
 *
 * @author API Key Framework
 * @version 1.0
 */
@RestController
public class AccessLogController {

    @Autowired
    private AccessLogService accessLogService;

    /**
     * 分页查询访问日志
     *
     * @param page           页码，从0开始
     * @param size           每页大小
     * @param sort           排序字段
     * @param direction      排序方向
     * @param apiKeyId       API Key ID过滤
     * @param startTime      开始时间
     * @param endTime        结束时间
     * @param clientIp       客户端IP过滤
     * @param responseStatus 响应状态过滤
     * @return 分页结果
     */
    @GetMapping("/api/access-logs")
    public ResponseEntity<Map<String, Object>> getAccessLogs(
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size,
            @RequestParam(defaultValue = "accessTime") String sort,
            @RequestParam(defaultValue = "desc") String direction,
            @RequestParam(required = false) Long apiKeyId,
            @RequestParam(required = false) String apiKeyValue,
            @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime startTime,
            @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime endTime,
            @RequestParam(required = false) String clientIp,
            @RequestParam(required = false) Integer responseStatus) {

        try {
            Sort.Direction sortDirection = "desc".equalsIgnoreCase(direction) ?
                    Sort.Direction.DESC : Sort.Direction.ASC;
            Pageable pageable = PageRequest.of(page, size, Sort.by(sortDirection, sort));

            Page<AccessLog> accessLogs;
            
            // 如果提供了apiKeyValue，则使用API Key值进行查询
            if (apiKeyValue != null && !apiKeyValue.trim().isEmpty()) {
                accessLogs = accessLogService.findAccessLogs(
                        apiKeyValue.trim(), clientIp, responseStatus, null, startTime, endTime, pageable);
            } else {
                // 否则使用原有的apiKeyId查询，但排除ADMIN_REQUEST类型的记录
                accessLogs = accessLogService.getAccessLogsExcludingAdmin(
                        apiKeyId, startTime, endTime, clientIp, responseStatus, pageable);
            }

            Map<String, Object> response = new HashMap<>();
            response.put("content", accessLogs.getContent());
            response.put("totalElements", accessLogs.getTotalElements());
            response.put("totalPages", accessLogs.getTotalPages());
            response.put("currentPage", accessLogs.getNumber());
            response.put("size", accessLogs.getSize());

            return ResponseEntity.ok(response);
        } catch (Exception e) {
            Map<String, Object> errorResponse = new HashMap<>();
            errorResponse.put("success", false);
            errorResponse.put("message", "查询访问日志失败: " + e.getMessage());
            return ResponseEntity.status(500).body(errorResponse);
        }
    }

    /**
     * 根据API Key查询访问日志
     *
     * @param apiKeyId API Key ID
     * @param page     页码
     * @param size     每页大小
     * @return 分页结果
     */
    @GetMapping("/api/access-logs/by-apikey/{apiKeyId}")
    public ResponseEntity<Map<String, Object>> getAccessLogsByApiKey(
            @PathVariable Long apiKeyId,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size) {

        Pageable pageable = PageRequest.of(page, size, Sort.by(Sort.Direction.DESC, "accessTime"));
        Page<AccessLog> accessLogs = accessLogService.getAccessLogs(apiKeyId, null, null, null, null, pageable);

        Map<String, Object> response = new HashMap<>();
        response.put("content", accessLogs.getContent());
        response.put("totalElements", accessLogs.getTotalElements());
        response.put("totalPages", accessLogs.getTotalPages());
        response.put("currentPage", accessLogs.getNumber());
        response.put("size", accessLogs.getSize());

        return ResponseEntity.ok(response);
    }

    /**
     * 根据时间范围查询访问日志
     *
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @param page      页码
     * @param size      每页大小
     * @return 分页结果
     */
    @GetMapping("/api/access-logs/by-time-range")
    public ResponseEntity<Map<String, Object>> getAccessLogsByTimeRange(
            @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime startTime,
            @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime endTime,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size) {

        Pageable pageable = PageRequest.of(page, size, Sort.by(Sort.Direction.DESC, "accessTime"));
        Page<AccessLog> accessLogs = accessLogService.getAccessLogs(null, startTime, endTime, null, null, pageable);

        Map<String, Object> response = new HashMap<>();
        response.put("content", accessLogs.getContent());
        response.put("totalElements", accessLogs.getTotalElements());
        response.put("totalPages", accessLogs.getTotalPages());
        response.put("currentPage", accessLogs.getNumber());
        response.put("size", accessLogs.getSize());

        return ResponseEntity.ok(response);
    }

    /**
     * 根据客户端IP查询访问日志
     *
     * @param clientIp 客户端IP
     * @param page     页码
     * @param size     每页大小
     * @return 分页结果
     */
    @GetMapping("/api/access-logs/by-client-ip/{clientIp}")
    public ResponseEntity<Map<String, Object>> getAccessLogsByClientIp(
            @PathVariable String clientIp,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size) {

        Pageable pageable = PageRequest.of(page, size, Sort.by(Sort.Direction.DESC, "accessTime"));
        Page<AccessLog> accessLogs = accessLogService.findByClientIp(clientIp, pageable);

        Map<String, Object> response = new HashMap<>();
        response.put("content", accessLogs.getContent());
        response.put("totalElements", accessLogs.getTotalElements());
        response.put("totalPages", accessLogs.getTotalPages());
        response.put("currentPage", accessLogs.getNumber());
        response.put("size", accessLogs.getSize());

        return ResponseEntity.ok(response);
    }

    /**
     * 根据响应状态查询访问日志
     *
     * @param responseStatus 响应状态
     * @param page           页码
     * @param size           每页大小
     * @return 分页结果
     */
    @GetMapping("/api/access-logs/by-response-status/{responseStatus}")
    public ResponseEntity<Map<String, Object>> getAccessLogsByResponseStatus(
            @PathVariable Integer responseStatus,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size) {

        Pageable pageable = PageRequest.of(page, size, Sort.by(Sort.Direction.DESC, "accessTime"));
        Page<AccessLog> accessLogs = accessLogService.findByResponseStatus(responseStatus, pageable);

        Map<String, Object> response = new HashMap<>();
        response.put("content", accessLogs.getContent());
        response.put("totalElements", accessLogs.getTotalElements());
        response.put("totalPages", accessLogs.getTotalPages());
        response.put("currentPage", accessLogs.getNumber());
        response.put("size", accessLogs.getSize());

        return ResponseEntity.ok(response);
    }

    /**
     * 搜索访问日志
     *
     * @param keyword 关键字
     * @param page    页码
     * @param size    每页大小
     * @return 分页结果
     */
    @GetMapping("/api/access-logs/search")
    public ResponseEntity<Map<String, Object>> searchAccessLogs(
            @RequestParam String keyword,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size) {

        Pageable pageable = PageRequest.of(page, size, Sort.by(Sort.Direction.DESC, "accessTime"));
        Page<AccessLog> accessLogs = accessLogService.searchAccessLogs(keyword, pageable);

        Map<String, Object> response = new HashMap<>();
        response.put("content", accessLogs.getContent());
        response.put("totalElements", accessLogs.getTotalElements());
        response.put("totalPages", accessLogs.getTotalPages());
        response.put("currentPage", accessLogs.getNumber());
        response.put("size", accessLogs.getSize());

        return ResponseEntity.ok(response);
    }

    /**
     * 获取访问日志统计信息
     *
     * @return 统计信息
     */
    @GetMapping("/api/access-logs/stats")
    public ResponseEntity<Map<String, Object>> getAccessLogStats() {
        try {
            Map<String, Object> stats = accessLogService.getAccessLogStats();
            return ResponseEntity.ok(stats);
        } catch (Exception e) {
            Map<String, Object> errorResponse = new HashMap<>();
            errorResponse.put("success", false);
            errorResponse.put("message", "获取访问统计失败: " + e.getMessage());
            return ResponseEntity.status(500).body(errorResponse);
        }
    }

    /**
     * 获取访问统计信息（兼容旧接口）
     *
     * @return 统计信息
     */
    @GetMapping("/access-logs/stats")
    public ResponseEntity<Map<String, Object>> getAccessStats() {
        try {
            Map<String, Object> stats = accessLogService.getAccessLogStats();
            return ResponseEntity.ok(stats);
        } catch (Exception e) {
            Map<String, Object> errorResponse = new HashMap<>();
            errorResponse.put("success", false);
            errorResponse.put("message", "获取访问统计失败: " + e.getMessage());
            return ResponseEntity.status(500).body(errorResponse);
        }
    }

    /**
     * 获取热门API Key统计
     *
     * @param limit 返回数量限制
     * @return 热门API Key列表
     */
    @GetMapping("/stats/top-apikeys")
    public ResponseEntity<List<Map<String, Object>>> getTopApiKeys(
            @RequestParam(defaultValue = "10") int limit) {
        List<Map<String, Object>> topApiKeys = accessLogService.getTopApiKeys(limit);
        return ResponseEntity.ok(topApiKeys);
    }

    /**
     * 获取热门访问路径统计
     *
     * @param limit 返回数量限制
     * @return 热门路径列表
     */
    @GetMapping("/stats/top-paths")
    public ResponseEntity<List<Map<String, Object>>> getTopPaths(
            @RequestParam(defaultValue = "10") int limit) {
        List<Map<String, Object>> topPaths = accessLogService.getTopPaths(limit);
        return ResponseEntity.ok(topPaths);
    }

    /**
     * 获取热门客户端IP统计
     *
     * @param limit 返回数量限制
     * @return 热门IP列表
     */
    @GetMapping("/stats/top-client-ips")
    public ResponseEntity<List<Map<String, Object>>> getTopClientIps(
            @RequestParam(defaultValue = "10") int limit) {
        List<Map<String, Object>> topClientIps = accessLogService.getTopClientIps(limit);
        return ResponseEntity.ok(topClientIps);
    }

    /**
     * 获取每日访问统计
     *
     * @param days 统计天数
     * @return 每日统计列表
     */
    @GetMapping("/api/access-logs/stats/daily")
    public ResponseEntity<List<Map<String, Object>>> getDailyStats(
            @RequestParam(defaultValue = "7") int days) {
        List<Map<String, Object>> dailyStats = accessLogService.getDailyStats(days);
        return ResponseEntity.ok(dailyStats);
    }

    /**
     * 获取每小时访问统计
     *
     * @param hours 统计小时数
     * @return 每小时统计列表
     */
    @GetMapping("/api/access-logs/stats/hourly")
    public ResponseEntity<List<Map<String, Object>>> getHourlyStats(
            @RequestParam(defaultValue = "24") int hours) {
        List<Map<String, Object>> hourlyStats = accessLogService.getHourlyStats(hours);
        return ResponseEntity.ok(hourlyStats);
    }

    /**
     * 导出访问日志
     *
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @param format    导出格式（csv/excel）
     * @return 导出文件
     */
    @GetMapping("/api/access-logs/export")
    public ResponseEntity<String> exportAccessLogs(
            @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime startTime,
            @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime endTime,
            @RequestParam(defaultValue = "csv") String format) {

        String exportData = accessLogService.exportToCsv(startTime, endTime, null, null);
        return ResponseEntity.ok(exportData);
    }
}